﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate.Cfg;
using Commander.DataLayer.Conventions;
using FluentNHibernate.Cfg.Db;
using FluentNHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using NHibernate;
using System.IO;
using FluentNHibernate.Automapping;

namespace Commander.DataLayer {
  public class NHibernateSessionHelper {

    private static AutoPersistenceModel model;
    private static AutoPersistenceModel Model {
      get {
        if (model == null) {
          model = new AutoPersistenceModel();
          model.IgnoreBase<DomainBase>();
        }

        return model;
      }
    }

    private static ISessionFactory sessionFactory;
    private static ISessionFactory SessionFactory {
      get {
        if (sessionFactory == null) {
          sessionFactory = BuildMapppings().BuildSessionFactory();
        }
        return sessionFactory;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    /// <remarks>Mappings based on calling assembly</remarks>
    public static ISessionFactory CreateNewDatabaseSessionFactory() {
      return BuildMapppings()
            .ExposeConfiguration(BuildSchema)
            .BuildSessionFactory();
    }

    public static ISessionFactory CreateNewDatabaseSessionFactoryWithDBFile(string file) {
      if (File.Exists(file)) {
        File.Delete(file);
      }

      sessionFactory = BuildMapppings(file)
            .ExposeConfiguration(BuildSchema)
            .BuildSessionFactory();
      return sessionFactory;

    }

    private static void BuildSchema(Configuration config) {
      new SchemaExport(config)
        .Create(false, true);
    }

    private static FluentConfiguration BuildMapppings() {
      return BuildMapppings(null);
    }

    public static ISession OpenSession() {
      return SessionFactory.OpenSession();
    }

    private static FluentConfiguration BuildMapppings(string file) {
      return Fluently.Configure()
                      .Database(
                          Config(file)
                      )
       .Mappings(m => m.AutoMappings.Add(Model.AddEntityAssembly(typeof(DomainBase).Assembly)
                                                              .Where(w => w.BaseType == typeof(DomainBase))
                                                              .Conventions.Add<PrimaryKeyConvention>()
                                                              .Conventions.Add<CustomForeignKeyConvention>()
                                                              .Conventions.Add<ClassMappingConvention>()
                                                              ));
    }
   
    private static IPersistenceConfigurer Config(string DbFile) {
      IPersistenceConfigurer config;
      if (DbFile == null) {
        config = MsSqlConfiguration.MsSql2005.ConnectionString(con => con.Is(DomainConfig.Instance.ConnectionString));
      }
      else {
        config = SQLiteConfiguration.Standard.UsingFile(DbFile);
      }

      return config;
    }

  }

}
